#include <iostream>
#include <memory>
#include "Reactor.hpp"
#include "Log.hpp"
#include "Listener.hpp"
#include "Http.hpp"
#include "TcpServer.hpp"

using namespace myLog;


//这里就简单模拟一下就好了，直接以txt文本返回
void Login(HttpRequest& req, HttpResponse& resp){
    //此时，不知道参数在正文还是在uri上
    //但是，在HttpRequest类内，用参数_args保存了！
    std::string args = req.GetArgs() == "" ? req.GetText() : req.GetArgs();
    resp.SetCodeAndDesc(200);

    //正文部分
    std::string resp_text = "haha, your username and password is looked : " + args;
    resp.SetText(resp_text);

    //设置报头 
    resp.SetHeaders("Content-Length", std::to_string(resp_text.size()));
    resp.SetHeaders("Content-Type", MimeTypes().getMimeType(".txt"));
}

void Register(HttpRequest& req, HttpResponse& resp){
    std::string args = req.GetArgs() == "" ? req.GetText() : req.GetArgs();
    resp.SetCodeAndDesc(200);

    std::string resp_text = "register : " + args;
    resp.SetText(resp_text);

    resp.SetHeaders("Content-Length", std::to_string(resp_text.size()));
    resp.SetHeaders("Content-Type", MimeTypes().getMimeType(".txt"));
}

// ./xx.exe serverport

int main(int argc, char* argv[]){
    if(argc != 2){
        std::cout << "please use ./ReactorServer.exe server_port" << std::endl;
        exit(USAGE_ERROR);
    }
    int input_port = std::stoi(argv[1]); 

    //把日志使能打开
    ENABLE_Display_LOG_STRATEGY();

    //0.需要先把专门用来监听的套接字创建好，拿到端口号
    std::shared_ptr<Connection> listener = std::make_shared<Listener>(input_port);
    int port = listener->Getport();

    // 1.今天要处理的任务 -> HTTP,需要先获得此次服务的端口号
    std::shared_ptr<Http> http = std::make_shared<Http>();
    http->RegisterRoute("/login", Login);
    http->RegisterRoute("/register", Register);


    //把http协议的服务注册到连接
    listener->RegsiterHandler([&http](std::string& inbuffer)->std::string{
        LOG(LogLevel::DEBUG) << "进入到处理函数...";
        return http->HandleHttpRequest(inbuffer);
    });

    //但是，一开始来说，epoll模型内是什么都没有的！也就是没办法关注
    //所以，需要想办法，把Listenner放到内核中，和底层的哈希中
    std::unique_ptr<Reactor> R = std::make_unique<Reactor>();
    R->AddConnection(listener);
    R->Loop();
    return 0;
}